home *** CD-ROM | disk | FTP | other *** search
/ BBS in a Box 3 / BBS in a box - Trilogy III.iso / Files / Prog / B-C / Berkeley-yacc-mpw / verbose.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-10-14  |  8.1 KB  |  367 lines  |  [TEXT/MPS ]

  1. /*
  2.  * Copyright (c) 1989 The Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * This code is derived from software contributed to Berkeley by
  6.  * Robert Paul Corbett.
  7.  *
  8.  * Redistribution and use in source and binary forms, with or without
  9.  * modification, are permitted provided that the following conditions
  10.  * are met:
  11.  * 1. Redistributions of source code must retain the above copyright
  12.  *    notice, this list of conditions and the following disclaimer.
  13.  * 2. Redistributions in binary form must reproduce the above copyright
  14.  *    notice, this list of conditions and the following disclaimer in the
  15.  *    documentation and/or other materials provided with the distribution.
  16.  * 3. All advertising materials mentioning features or use of this software
  17.  *    must display the following acknowledgement:
  18.  *    This product includes software developed by the University of
  19.  *    California, Berkeley and its contributors.
  20.  * 4. Neither the name of the University nor the names of its contributors
  21.  *    may be used to endorse or promote products derived from this software
  22.  *    without specific prior written permission.
  23.  *
  24.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  25.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  26.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  27.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  28.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  29.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  30.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  31.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  32.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  33.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  34.  * SUCH DAMAGE.
  35.  */
  36.  
  37. #ifndef lint
  38. static char sccsid[] = "@(#)verbose.c    5.3 (Berkeley) 1/20/91";
  39. #endif /* not lint */
  40.  
  41. #include "defs.h"
  42.  
  43. static short *null_rules;
  44.  
  45. verbose()
  46. {
  47.     register int i;
  48.  
  49.     if (!vflag) return;
  50.  
  51.     null_rules = (short *) MALLOC(nrules*sizeof(short));
  52.     if (null_rules == 0) no_space();
  53.     fprintf(verbose_file, "\f\n");
  54.     for (i = 0; i < nstates; i++)
  55.     print_state(i);
  56.     FREE(null_rules);
  57.  
  58.     if (nunused)
  59.     log_unused();
  60.     if (SRtotal || RRtotal)
  61.     log_conflicts();
  62.  
  63.     fprintf(verbose_file, "\n\n%d terminals, %d nonterminals\n", ntokens,
  64.         nvars);
  65.     fprintf(verbose_file, "%d grammar rules, %d states\n", nrules - 2, nstates);
  66. }
  67.  
  68.  
  69. log_unused()
  70. {
  71.     register int i;
  72.     register short *p;
  73.  
  74.     fprintf(verbose_file, "\n\nRules never reduced:\n");
  75.     for (i = 3; i < nrules; ++i)
  76.     {
  77.     if (!rules_used[i])
  78.     {
  79.         fprintf(verbose_file, "\t%s :", symbol_name[rlhs[i]]);
  80.         for (p = ritem + rrhs[i]; *p >= 0; ++p)
  81.         fprintf(verbose_file, " %s", symbol_name[*p]);
  82.         fprintf(verbose_file, "  (%d)\n", i - 2);
  83.     }
  84.     }
  85. }
  86.  
  87.  
  88. log_conflicts()
  89. {
  90.     register int i;
  91.  
  92.     fprintf(verbose_file, "\n\n");
  93.     for (i = 0; i < nstates; i++)
  94.     {
  95.     if (SRconflicts[i] || RRconflicts[i])
  96.     {
  97.         fprintf(verbose_file, "State %d contains ", i);
  98.         if (SRconflicts[i] == 1)
  99.         fprintf(verbose_file, "1 shift/reduce conflict");
  100.         else if (SRconflicts[i] > 1)
  101.         fprintf(verbose_file, "%d shift/reduce conflicts",
  102.             SRconflicts[i]);
  103.         if (SRconflicts[i] && RRconflicts[i])
  104.         fprintf(verbose_file, ", ");
  105.         if (RRconflicts[i] == 1)
  106.         fprintf(verbose_file, "1 reduce/reduce conflict");
  107.         else if (RRconflicts[i] > 1)
  108.         fprintf(verbose_file, "%d reduce/reduce conflicts",
  109.             RRconflicts[i]);
  110.         fprintf(verbose_file, ".\n");
  111.     }
  112.     }
  113. }
  114.  
  115.  
  116. print_state(state)
  117. int state;
  118. {
  119.     if (state)
  120.     fprintf(verbose_file, "\n\n");
  121.     if (SRconflicts[state] || RRconflicts[state])
  122.     print_conflicts(state);
  123.     fprintf(verbose_file, "state %d\n", state);
  124.     print_core(state);
  125.     print_nulls(state);
  126.     print_actions(state);
  127. }
  128.  
  129.  
  130. print_conflicts(state)
  131. int state;
  132. {
  133.     register int symbol, act, number;
  134.     register action *p;
  135.  
  136.     symbol = -1;
  137.     for (p = parser[state]; p; p = p->next)
  138.     {
  139.     if (p->suppressed == 2)
  140.         continue;
  141.  
  142.     if (p->symbol != symbol)
  143.     {
  144.         symbol = p->symbol;
  145.         number = p->number;
  146.         if (p->action_code == SHIFT)
  147.         act = SHIFT;
  148.         else
  149.         act = REDUCE;
  150.     }
  151.     else if (p->suppressed == 1)
  152.     {
  153.         if (state == final_state && symbol == 0)
  154.         {
  155.         fprintf(verbose_file, "%d: shift/reduce conflict \
  156. (accept, reduce %d) on $end\n", state, p->number - 2);
  157.         }
  158.         else
  159.         {
  160.         if (act == SHIFT)
  161.         {
  162.             fprintf(verbose_file, "%d: shift/reduce conflict \
  163. (shift %d, reduce %d) on %s\n", state, number, p->number - 2,
  164.                 symbol_name[symbol]);
  165.         }
  166.         else
  167.         {
  168.             fprintf(verbose_file, "%d: reduce/reduce conflict \
  169. (reduce %d, reduce %d) on %s\n", state, number - 2, p->number - 2,
  170.                 symbol_name[symbol]);
  171.         }
  172.         }
  173.     }
  174.     }
  175. }
  176.  
  177.  
  178. print_core(state)
  179. int state;
  180. {
  181.     register int i;
  182.     register int k;
  183.     register int rule;
  184.     register core *statep;
  185.     register short *sp;
  186.     register short *sp1;
  187.  
  188.     statep = state_table[state];
  189.     k = statep->nitems;
  190.  
  191.     for (i = 0; i < k; i++)
  192.     {
  193.     sp1 = sp = ritem + statep->items[i];
  194.  
  195.     while (*sp >= 0) ++sp;
  196.     rule = -(*sp);
  197.     fprintf(verbose_file, "\t%s : ", symbol_name[rlhs[rule]]);
  198.  
  199.         for (sp = ritem + rrhs[rule]; sp < sp1; sp++)
  200.         fprintf(verbose_file, "%s ", symbol_name[*sp]);
  201.  
  202.     putc('.', verbose_file);
  203.  
  204.     while (*sp >= 0)
  205.     {
  206.         fprintf(verbose_file, " %s", symbol_name[*sp]);
  207.         sp++;
  208.     }
  209.     fprintf(verbose_file, "  (%d)\n", -2 - *sp);
  210.     }
  211. }
  212.  
  213.  
  214. print_nulls(state)
  215. int state;
  216. {
  217.     register action *p;
  218.     register int i, j, k, nnulls;
  219.  
  220.     nnulls = 0;
  221.     for (p = parser[state]; p; p = p->next)
  222.     {
  223.     if (p->action_code == REDUCE &&
  224.         (p->suppressed == 0 || p->suppressed == 1))
  225.     {
  226.         i = p->number;
  227.         if (rrhs[i] + 1 == rrhs[i+1])
  228.         {
  229.         for (j = 0; j < nnulls && i > null_rules[j]; ++j)
  230.             continue;
  231.  
  232.         if (j == nnulls)
  233.         {
  234.             ++nnulls;
  235.             null_rules[j] = i;
  236.         }
  237.         else if (i != null_rules[j])
  238.         {
  239.             ++nnulls;
  240.             for (k = nnulls - 1; k > j; --k)
  241.             null_rules[k] = null_rules[k-1];
  242.             null_rules[j] = i;
  243.         }
  244.         }
  245.     }
  246.     }
  247.  
  248.     for (i = 0; i < nnulls; ++i)
  249.     {
  250.     j = null_rules[i];
  251.     fprintf(verbose_file, "\t%s : .  (%d)\n", symbol_name[rlhs[j]],
  252.         j - 2);
  253.     }
  254.     fprintf(verbose_file, "\n");
  255. }
  256.  
  257.  
  258. print_actions(stateno)
  259. int stateno;
  260. {
  261.     register action *p;
  262.     register shifts *sp;
  263.     register int as;
  264.  
  265.     if (stateno == final_state)
  266.     fprintf(verbose_file, "\t$end  accept\n");
  267.  
  268.     p = parser[stateno];
  269.     if (p)
  270.     {
  271.     print_shifts(p);
  272.     print_reductions(p, defred[stateno]);
  273.     }
  274.  
  275.     sp = shift_table[stateno];
  276.     if (sp && sp->nshifts > 0)
  277.     {
  278.     as = accessing_symbol[sp->shift[sp->nshifts - 1]];
  279.     if (ISVAR(as))
  280.         print_gotos(stateno);
  281.     }
  282. }
  283.  
  284.  
  285. print_shifts(p)
  286. register action *p;
  287. {
  288.     register int count;
  289.     register action *q;
  290.  
  291.     count = 0;
  292.     for (q = p; q; q = q->next)
  293.     {
  294.     if (q->suppressed < 2 && q->action_code == SHIFT)
  295.         ++count;
  296.     }
  297.  
  298.     if (count > 0)
  299.     {
  300.     for (; p; p = p->next)
  301.     {
  302.         if (p->action_code == SHIFT && p->suppressed == 0)
  303.         fprintf(verbose_file, "\t%s  shift %d\n",
  304.                 symbol_name[p->symbol], p->number);
  305.     }
  306.     }
  307. }
  308.  
  309.  
  310. print_reductions(p, defred)
  311. register action *p;
  312. register int defred;
  313. {
  314.     register int k, anyreds;
  315.     register action *q;
  316.  
  317.     anyreds = 0;
  318.     for (q = p; q ; q = q->next)
  319.     {
  320.     if (q->action_code == REDUCE && q->suppressed < 2)
  321.     {
  322.         anyreds = 1;
  323.         break;
  324.     }
  325.     }
  326.  
  327.     if (anyreds == 0)
  328.     fprintf(verbose_file, "\t.  error\n");
  329.     else
  330.     {
  331.     for (; p; p = p->next)
  332.     {
  333.         if (p->action_code == REDUCE && p->number != defred)
  334.         {
  335.         k = p->number - 2;
  336.         if (p->suppressed == 0)
  337.             fprintf(verbose_file, "\t%s  reduce %d\n",
  338.                 symbol_name[p->symbol], k);
  339.         }
  340.     }
  341.  
  342.         if (defred > 0)
  343.         fprintf(verbose_file, "\t.  reduce %d\n", defred - 2);
  344.     }
  345. }
  346.  
  347.  
  348. print_gotos(stateno)
  349. int stateno;
  350. {
  351.     register int i, k;
  352.     register int as;
  353.     register short *to_state;
  354.     register shifts *sp;
  355.  
  356.     putc('\n', verbose_file);
  357.     sp = shift_table[stateno];
  358.     to_state = sp->shift;
  359.     for (i = 0; i < sp->nshifts; ++i)
  360.     {
  361.     k = to_state[i];
  362.     as = accessing_symbol[k];
  363.     if (ISVAR(as))
  364.         fprintf(verbose_file, "\t%s  goto %d\n", symbol_name[as], k);
  365.     }
  366. }
  367.